<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=9"/>
    <title>Wi-Fi Host Driver (WHD): Main Page</title>
    <link href="tabs.css" rel="stylesheet" type="text/css"/>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="dynsections.js"></script>
    <link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(initResizable);
/* @license-end */</script>
    <link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
    <link href="doxygen.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
      <div id="titlearea" style="font-family:verdana;">
        <table border='0' cellpadding='0' cellspacing='0' width="98%">
          <tr style="height:20px"><td>&nbsp;</td></tr>
          <tr style="border-collapse: collapse; padding: 0;">
            <td style="width:20px"></td>
            <td style="width:117px"><img src="cypress_logo.png" alt="Cypress Logo" /></td>
            <td style="width:20px;background-image:url('cypresslogo_line.png');"></td>
            <td style="vertical-align:middle; text-align:center; font: bold 25px/100% Verdana, Arial, Helvetica, sans-serif;background-image:url('cypresslogo_line.png');">
              Wi-Fi Host Driver (WHD) Public API Reference Guide
            </td>
          </tr>
          <tr><td>&nbsp;</td></tr>
        </table>
    </div>
    <!-- end header part -->
<!-- Generated by Doxygen 1.8.15 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;"
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('index.html','');});
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="PageDoc"><div class="header">
  <div class="headertitle">
<div class="title">Wi-Fi Host Driver (WHD) Documentation</div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="overview"></a>
WHD Overview</h1>
<p>The WHD is an independent, embedded Wi-Fi Host Driver that provides a set of APIs to interact with Cypress WLAN chips. The WHD is an independent firmware product that is easily portable to any embedded software environment, including popular IOT frameworks like Mbed OS, Amazon FreeRTOS, etc. Hence, the WHD includes hooks for RTOS and TCP/IP network abstraction layers. <br />
 The WHD requires the following services: </p><ul>
<li>
<b>HAL:</b> High-level abstraction layer that provides access to hardware like SDIO/SPI host controllers within the platform. </li>
<li>
<b>RTOS:</b> The WHD uses the abstraction layer to access RTOS functionality like threads, semaphores etc. This is the same interface that the Cypress Middleware uses. </li>
</ul>
<p><br />
</p>
<h1><a class="anchor" id="whd_features"></a>
WHD Features</h1>
<ul>
<li>
Supports Wi-Fi Station (STA) and AP mode of operation. </li>
<li>
Supports concurrent operation of STA and AP interface. </li>
<li>
Includes multiple security support like WPA2, WPA3, and open. </li>
<li>
Provides function to perform Advanced Power Management. </li>
<li>
Supports low power offloads, including ARP and packet filters. </li>
<li>
Includes WFA Pre-certification support for 802.11n and WPA3. </li>
</ul>
<p><br />
</p>
<h1><a class="anchor" id="whd_folder_struct"></a>
WHD Folder Structure</h1>
<ul>
<li>
whd\src - Core WHD files </li>
<li>
whd\inc - WHD API files </li>
<li>
whd\resources - WLAN Firmware </li>
<li>
whd.mk - A simple make file to build a <em>libwhd.a</em> library. </li>
</ul>
<p><br />
</p>
<h1><a class="anchor" id="whd_architecture"></a>
WHD Architecture</h1>
<p>The WHD consists of 3 different components as shown in the following architectural diagram. Blocks highlighted in red are external dependencies for the WHD, blue ones are Porting layer and black ones are WHD core.<br />
 </p><div class="image"> <img src="whd_arch.png" alt="whd_arch.png" width="600px" class="inline"/>
</div><p><br />
 </p>
<h1><a class="anchor" id="whd_porting"></a>
Porting WHD</h1>
<p>To port the WHD, implement the following APIs or Function Pointers (shown in the the WHD Architecture section diagram), so that the WHD is functional:</p>
<ul>
<li>
<a href="#_CY_RTOS_API">CY RTOS API</a> </li>
<li>
<a href="#_CY_HAL_Resource_API">CY HAL Resource API</a> </li>
<li>
<a href="#_Buffer_Interface_API">Buffer Interface API</a> </li>
<li>
<a href="#_Network_Interface_API">Network Interface API</a> </li>
<li>
<a href="#_CY_HAL_SPI/SDIO_Bus_API">CY HAL SPI/SDIO Bus API</a> </li>
</ul>
<p><br />
 </p><h2><a class="anchor" id="_CY_RTOS_API"></a>CY RTOS API</h2>
<p>The CY RTOS API provides prototypes for functions that allow the WHD to use RTOS functionality, such as threads, semaphores, and timing functions.<br />
You must implement the appropriate functions in your code. See <b><a href="whd_rtos.c">here</a></b> for an example implementation. </p><table class="doxtable">
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd"><b>Function</b></p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd"><b>Description</b></p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_create_thread</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Create RTOS thread.</p>
<p class="intertd"></p>
<p class="intertd">The WHD calls this function to create the main WHD thread.</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_terminate_thread</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Terminate the RTOS thread.</p>
<p class="intertd"></p>
<p class="intertd">The WHD calls this function to terminate WHD main thread created using cy_rtos_create_thread. It is called after calling cy_rtos_join_thread().</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_join_thread</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Join the RTOS thread.</p>
<p class="intertd"></p>
<p class="intertd">The WHD calls this function so that any resources that were allocated for it are cleaned up. It is called by WHD before cy_rtos_terminate_thread()</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_get_time</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">To provide time in milliseconds since RTOS start</p>
<p class="intertd"></p>
<p class="intertd">The WHD uses this to get the time in milliseconds.</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_delay_milliseconds</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Delay for a specified number of milliseconds.</p>
<p class="intertd"></p>
<p class="intertd">The WHD calls this function to obtain the time delay.</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_init_semaphore</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Create a semaphore.</p>
<p class="intertd"></p>
<p class="intertd">The WHD uses only binary semaphore, this function is used to init a semaphore</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_get_semaphore</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Get/Acquire a semaphore</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_set_semaphore</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Set/Release a semaphore</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cy_rtos_deinit_semaphore</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">Deletes a semaphore</p>
<p class="intertd"></p>
<p class="intertd">This function frees the resources associated with a semaphore.</p>
<p class="endtd"></p>
</td></tr>
</table>
<p><br />
 </p><h2><a class="anchor" id="_CY_HAL_Resource_API"></a>CY HAL Resource API</h2>
<p>The Wi-Fi firmware, NVRAM, and CLM BLOB information are treated as resources to be downloaded onto the Wi-Fi chip. Refer to the file <em><a class="el" href="whd__resource__api_8h.html" title="Prototypes of functions for providing external resources to the radio driver.">inc\whd_resource_api.h</a></em> for a detailed description. <br />
You must implement the appropriate function pointers in your code. See <b><a href="whd_resources.c">here</a></b> for an example implementation. </p><table class="doxtable">
<tr>
<td width="210"><p class="starttd"></p>
<p class="intertd"><b>Function</b></p>
<p class="endtd"></p>
</td><td width="461"><p class="starttd"></p>
<p class="intertd"><b>Description</b></p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="210"><p class="starttd"></p>
<p class="intertd">whd_resource_size</p>
<p class="endtd"></p>
</td><td width="461"><p class="starttd"></p>
<p class="intertd">Gets the size of the resource for respective resource type</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="210"><p class="starttd"></p>
<p class="intertd">whd_get_resource_block</p>
<p class="endtd"></p>
</td><td width="461"><p class="starttd"></p>
<p class="intertd">Gets the resource block for specified resource type</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="210"><p class="starttd"></p>
<p class="intertd">whd_get_resource_no_of_blocks</p>
<p class="endtd"></p>
</td><td width="461"><p class="starttd"></p>
<p class="intertd">Gets block count for the specified resource_type</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="210"><p class="starttd"></p>
<p class="intertd">whd_get_resource_block_size</p>
<p class="endtd"></p>
</td><td width="461"><p class="starttd"></p>
<p class="intertd">Gets block size for the specified resource_type</p>
<p class="endtd"></p>
</td></tr>
</table>
<p><br />
 </p><h2><a class="anchor" id="_Buffer_Interface_API"></a>Buffer Interface API</h2>
<p>The WHD requires packet buffers to exchange information between the host and Wi-Fi firmware. Refer to the file <em><a class="el" href="whd__network__types_8h.html" title="Prototypes of functions corresponding to Buffer and Network Interface.">inc\whd_network_types.h</a></em> for a detailed description. <br />
You must implement the appropriate function pointers in your code. See <b><a href="cy_network_buffer.c">here</a></b> for an example implementation. </p><table class="doxtable">
<tr>
<td width="216"><p class="starttd"></p>
<p class="intertd"><b>Function</b></p>
<p class="endtd"></p>
</td><td width="450"><p class="starttd"></p>
<p class="intertd"><b>Description</b></p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="216"><p class="starttd"></p>
<p class="intertd">whd_host_buffer_get</p>
<p class="endtd"></p>
</td><td width="450">Allocates a packet buffer <br />
<br />
 You can implement this function by allocating a pre-existing packet from a pool, using a static buffer, or by dynamically allocating memory. The method chosen must match the way the network stack expects packet buffers to be allocated. Usually, the WHD requires a packet of size of WHD_LINK_MTU which includes the MTU and various other headers. Refer to <a class="el" href="whd__types_8h.html" title="Defines common data types used with WHD.">whd_types.h</a> to find the size of WHD_LINK_MTU. The following include expected return error codes other than WHD_SUCCESS: <ul>
<li>
<b>WHD_BUFFER_UNAVAILABLE_PERMANENT </b>: Attempt to allocate more than MTU size </li>
<li>
<b>WHD_BUFFER_UNAVAILABLE_TEMPORARY </b>: No Packet available in any pool </li>
<li>
<b>WHD_BUFFER_ALLOC_FAIL </b>: Packet allocation fails </li>
</ul>
</td></tr>
<tr>
<td width="216"><p class="starttd"></p>
<p class="intertd">whd_buffer_release</p>
<p class="endtd"></p>
</td><td width="450"><p class="starttd"></p>
<p class="intertd">Releases a packet buffer</p>
<p class="intertd"></p>
<p class="intertd">The WHD uses this function to indicate that it no longer requires a packet buffer. The buffer can then be released back into a pool for reuse, or the dynamically allocated memory can be freed, according to how the packet was allocated.</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="216"><p class="starttd"></p>
<p class="intertd">whd_buffer_get_current_piece_data_pointer</p>
<p class="endtd"></p>
</td><td width="450"><p class="starttd"></p>
<p class="intertd">Retrieves the current pointer of a packet buffer</p>
<p class="intertd"></p>
<p class="intertd">Since packet buffers usually need to be created with space at the front for additional headers, this function allows the WHD to get the current 'front' location pointer.</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="216"><p class="starttd"></p>
<p class="intertd">whd_buffer_get_current_piece_size</p>
<p class="endtd"></p>
</td><td width="450"><p class="starttd"></p>
<p class="intertd">Retrieves the size of a packet buffer</p>
<p class="intertd"></p>
<p class="intertd">Since packet buffers usually need to be created with space at the front for additional headers, the memory block used to contain a packet buffer will often be larger than the current size of the packet buffer data. This function allows the WHD to retrieve the current size of a packet buffer's data.</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="216"><p class="starttd"></p>
<p class="intertd">whd_buffer_set_size</p>
<p class="endtd"></p>
</td><td width="450"><p class="starttd"></p>
<p class="intertd">Sets the current length of a WHD packet buffer.</p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="216"><p class="starttd"></p>
<p class="intertd">whd_buffer_add_remove_at_front</p>
<p class="endtd"></p>
</td><td width="450"><p class="starttd"></p>
<p class="intertd">Moves the current pointer of a packet buffer</p>
<p class="intertd"></p>
<p class="intertd">Since packet buffers usually need to be created with space at the front for additional headers, this function allows the WHD to move the current 'front' location pointer. This ensures that the WHD has space to add headers to transmit packets, and that the network stack does not see the internal WHD headers on received packets.</p>
<p class="endtd"></p>
</td></tr>
</table>
<p><br />
</p><h2><a class="anchor" id="_Network_Interface_API"></a>Network Interface API</h2>
<p>The WHD calls this function pointer to pass the received TCP/IP data packet from WLAN. Refer to the file <em><a class="el" href="whd__network__types_8h.html" title="Prototypes of functions corresponding to Buffer and Network Interface.">inc\whd_network_types.h</a></em> for a detailed description. <br />
You must implement the appropriate function pointers in your code. See <b><a href="whd_network.c">here</a></b> for an example implementation. </p><table class="doxtable">
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd"><b>FUNCTION</b></p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd"><b>Description</b></p>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">whd_network_process_ethernet_data</p>
<p class="endtd"></p>
</td><td width="336"><p class="starttd"></p>
<p class="intertd">The WHD calls this function pointer to pass received data to the network stack. You must provide the definition of the function.</p>
<p class="intertd"></p>
<p class="intertd">This function pointer is called asynchronously in the context of the WHD thread whenever new data has arrived.</p>
<p class="intertd"></p>
<p class="intertd">Packet buffers are allocated within the WHD, and ownership is transferred to the network stack. The network stack or application is thus responsible for releasing the packet buffers. Most packet buffering systems have a pointer to the 'current point' within the packet buffer. When this function is called, the pointer points to the start of the Ethernet header. There are other inconsequential data before the Ethernet header.</p>
<p class="intertd"></p>
<p class="intertd">It is preferable that you implement this function simply by putting the received packet on a queue for processing by another thread. This avoids the WHD thread being unnecessarily tied up which would delay other packets being transmitted or received.</p>
<p class="endtd"></p>
</td></tr>
</table>
<p><br />
</p><h2><a class="anchor" id="_CY_HAL_SPI/SDIO_Bus_API"></a>CY HAL SPI/SDIO Bus API</h2>
<p>The WHD uses the following functions to access the host bus controller for SDIO or SPI buses. <br />
You must implement these functions in your code. See <b><a href="cyhal_sdhc.c">here</a></b> for an example implementation. <br />
 Based on the target environment implementation, replace and use these functions appropriately to ensure bus operations. </p><table class="doxtable">
<tr>
<td width="336"><h3><b>Function</b></h3>
<p class="endtd"></p>
</td><td width="336"><h3><b>Description</b></h3>
<p class="endtd"></p>
</td></tr>
<tr>
<td width="336">cyhal_spi_register_irq </td><td width="336">The SPI interrupt handler registration.  </td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cyhal_spi_transfer</p>
<p class="endtd"></p>
</td><td width="336">Writes a block out and receives a value. The total number of bytes sent and received will be the maximum of tx_length and rx_length. The bytes written will be padded with the value 0xff.  </td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cyhal_spi_irq_enable</p>
<p class="endtd"></p>
</td><td width="336">Configure SPI interrupt. This function is used for word-approach.  </td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cyhal_sdio_register_irq</p>
<p class="intertd"></p>
<p class="intertd">&#160;</p>
<p class="endtd"></p>
</td><td width="336">The SDIO interrupt handler registration.  </td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cyhal_sdio_irq_enable</p>
<p class="intertd"></p>
<p class="intertd">&#160;</p>
<p class="endtd"></p>
</td><td width="336">Configures the SDIO interrupt  </td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cyhal_sdio_send_cmd</p>
<p class="endtd"></p>
</td><td width="336">Sends a command to the SDIO block.  </td></tr>
<tr>
<td width="336"><p class="starttd"></p>
<p class="intertd">cyhal_sdio_bulk_transfer</p>
<p class="endtd"></p>
</td><td width="336">Performs a bulk data transfer (CMD=53) to the SDIO block.  </td></tr>
</table>
<p><br />
</p>
<h1><a class="anchor" id="power_up"></a>
WHD Power up sequence</h1>
<p>Before starting the WHD, perform the following steps: </p><ul>
<li>
Connect the WLAN chip to a 32 kHz reference clock and to the sleep clock input pin. </li>
<li>
<p class="startli">Toggle the WL_REG_ON pin shown in the WHD Power up sequence chart. </p><ul>
<li>
WL_REG_ON pin has same polarity for all the WLAN chips </li>
<li>
For SDIO Case, SHDC complete the SD Enumeration as per the “SDIO Simplified Specification.” Refer to <a href="https://www.sdcard.org/downloads/pls/">https://www.sdcard.org/downloads/pls/</a> “Part E1 Simplified”, “SDIO Simplified Specification,” section 3.1.2, flowchart in Figure 3-2. </li>
</ul>
<p><br />
</p>
<div class="image"> <img src="whd_power_up.png" alt="whd_power_up.png" width="600px" class="inline"/>
</div><p><br />
</p>
<p class="endli"></p>
</li>
</ul>
<h1><a class="anchor" id="modes"></a>
WHD Modes of Operation</h1>
<p>There are basically three modes of operation in WHD: </p><ul>
<li>
<a href="#_WHD_STA_or_AP_mode">WHD STA mode</a> </li>
<li>
<a href="#_WHD_STA_or_AP_mode">WHD AP mode</a> </li>
<li>
<a href="#_WHD_STA+AP_concurrent_mode">WHD STA+AP concurrent mode</a> </li>
</ul>
<p><br />
 </p><h2><a class="anchor" id="_WHD_STA_or_AP_mode"></a>WHD STA or AP mode</h2>
<p>The following example code shows the program flow for execution in STA/AP mode: </p><div class="fragment"><div class="line"><span class="preprocessor">#############################</span></div><div class="line">   File whd.h</div><div class="line"><span class="preprocessor">##############################</span></div><div class="line"><span class="comment">//Abstract struct</span></div><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>whd_driver *<a class="code" href="whd_8h.html#ac45015d82e65db891b463066873eca4f">whd_driver_t</a>;</div><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>whd_interface *<a class="code" href="whd_8h.html#a2e544c482ddbb690bbb95ce7174e79a0">whd_interface_t</a>;</div><div class="line"></div><div class="line"><span class="preprocessor">##############################</span></div><div class="line">   File app.c</div><div class="line"><span class="preprocessor">###############################</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="whd_8h.html">whd.h</a>&quot;</span></div><div class="line"></div><div class="line">app_start_whd()</div><div class="line">{</div><div class="line">    <a class="code" href="whd_8h.html#ac45015d82e65db891b463066873eca4f">whd_driver_t</a> whd_driver;</div><div class="line">    <a class="code" href="whd_8h.html#a2e544c482ddbb690bbb95ce7174e79a0">whd_interface_t</a> ifp;</div><div class="line"></div><div class="line">    <span class="comment">// Each wifi chip, will have it&#39;s own instance of whd_driver.</span></div><div class="line">    <span class="comment">// Each whd_driver may use multiple instance of whd_interface_t structs to define behavior and functionality.</span></div><div class="line">    <span class="comment">// Most of the WHD function calls take this structure as input.</span></div><div class="line">    <span class="comment">// The default primary interface is created automatically at the time of power up of wifi chip, whd_wifi_on(..).</span></div><div class="line">    <span class="comment">// Primary interface is STA/AP role neutral.</span></div><div class="line"></div><div class="line"></div><div class="line">    <span class="comment">// Call whd_init per wifi chip (in other words per bus slot, two SDIO Wifi chip requires two calls.)</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga286dde2ee65ac3ea5ae67a6e6ef25f0a">whd_init</a>(&amp;whd_driver, &amp;<a class="code" href="structwhd__init__config.html">whd_init_config_t</a>, &amp;<a class="code" href="structwhd__resource__source.html">whd_resource_source</a>, &amp;<a class="code" href="structwhd__buffer__funcs.html">whd_buffer_funcs</a>, &amp;<a class="code" href="structwhd__netif__funcs.html">whd_netif_funcs</a>);</div><div class="line"></div><div class="line">    <span class="comment">// Attach a bus SDIO or SPI</span></div><div class="line">    <a class="code" href="group__busapi.html#ga9f08c5241843cbe2ef06ffa8bfb5118d">whd_bus_sdio_attach</a>(whd_driver, &amp;whd_sdio_cfg, &amp;sdhc_obj);</div><div class="line">    <span class="comment">//or whd_bus_spi_attach(whd_driver, &amp;whd_spi_cfg, &amp;spi_obj);</span></div><div class="line"></div><div class="line">    ...</div><div class="line"></div><div class="line">    <span class="comment">// Switch on Wifi, download firmware and create a primary interface, returns whd_interface_t</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga1c8bf41b593cb947266f8690d495f381">whd_wifi_on</a>(whd_driver, &amp;ifp);</div><div class="line"></div><div class="line">    <span class="comment">//11a. Join to AP - Note that it doesn&#39;t take whd_driver, instead whd_interface_t</span></div><div class="line">    <a class="code" href="group__wifijoin.html#gac767814ae445f735b51686db20c780be">whd_wifi_join</a>(ifp , <span class="stringliteral">&quot;AP SSID&quot;</span>, <a class="code" href="whd__types_8h.html#aaeeea5666743710aa4f01ff264b27059a2b5521d2587803363849e1987775e78b">WHD_SECURITY_OPEN</a>, security_key, strlen(security_key), NULL);</div><div class="line">    <span class="comment">//whd_ifp will be in STA role from now on</span></div><div class="line"></div><div class="line">    <span class="comment">// or 11b. It can an start AP also here, then interface will be in AP role</span></div><div class="line">    <span class="comment">//whd_wifi_init_ap(ifp ..)</span></div><div class="line">    <span class="comment">//whd_wifi_start_ap(ifp);</span></div><div class="line"></div><div class="line">    <span class="comment">// Leave the AP</span></div><div class="line">    <a class="code" href="group__wifijoin.html#ga971ed7d8e459c715aa9bf3c52b563d8b">whd_wifi_leave</a>(ifp );</div><div class="line">    <span class="comment">// or Stop the AP</span></div><div class="line">    <span class="comment">//whd_wifi_stop_ap(ifp , ...);</span></div><div class="line"></div><div class="line">    <span class="comment">// Switch off Wifi</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga422587a9b104a871233a42aceb2141d2">whd_wifi_off</a>(ifp );</div><div class="line"></div><div class="line">    <span class="comment">//Deletes all the interface and De-init the whd, free whd_driver memory</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#gab7d6e59874922e5646e08e52082e32f5">whd_deinit</a>(ifp);</div><div class="line"></div><div class="line">    <span class="comment">// Detach a bus SDIO or SPI</span></div><div class="line">    <a class="code" href="group__busapi.html#gadeed66e792eed64cbb6a0deef1dbe2da">whd_bus_sdio_detach</a>(whd_driver);</div><div class="line">    <span class="comment">//or whd_bus_spi_detach(whd_driver);</span></div><div class="line">}</div></div><!-- fragment --><p> <br />
</p><h2><a class="anchor" id="_WHD_STA+AP_concurrent_mode"></a>WHD STA+AP concurrent mode</h2>
<p>The WHD supports STA+AP concurrent mode of operation. There is no support for STA+STA or AP+AP. For concurrent mode of operation, you need to create a secondary interface along with the primary interface. The primary interface must have an STA interface, and the secondary interface must have an AP interface. Running AP in the primary interface and running STA in the secondary interface is invalid. <br />
<br />
The following example code shows the flow for execution in STA+AP concurrent mode: </p><div class="fragment"><div class="line">app_start_whd()</div><div class="line">{</div><div class="line">    <a class="code" href="whd_8h.html#ac45015d82e65db891b463066873eca4f">whd_driver_t</a> whd_driver;</div><div class="line">    <a class="code" href="whd_8h.html#a2e544c482ddbb690bbb95ce7174e79a0">whd_interface_t</a> prim_ifp;</div><div class="line">    <a class="code" href="whd_8h.html#a2e544c482ddbb690bbb95ce7174e79a0">whd_interface_t</a> sec_ifp;</div><div class="line"></div><div class="line">    <span class="comment">// Each wifi chip, will have it&#39;s own instance of whd_driver</span></div><div class="line">    <span class="comment">// Each whd_driver may use multiple instance of whd_interface_t structs to define behavior and functionality.</span></div><div class="line">    <span class="comment">// Most of the WHD function calls take this structure as input.</span></div><div class="line">    <span class="comment">// The default primary interface is created automatically at the time of power up of wifi chip, whd_wifi_on(..).</span></div><div class="line">    <span class="comment">// Primary interface is STA/AP role neutral, but in case of concurrent mode of STA+AP mode, primary interface must have STA role only.</span></div><div class="line"></div><div class="line"></div><div class="line">    <span class="comment">// Call whd_init per wifi chip (in other words per bus slot, two SDIO Wifi chip requires two calls.)</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga286dde2ee65ac3ea5ae67a6e6ef25f0a">whd_init</a>(&amp;whd_driver, &amp;whd_init_cfg, &amp;<a class="code" href="structwhd__resource__source.html">whd_resource_source</a>, &amp;<a class="code" href="structwhd__buffer__funcs.html">whd_buffer_funcs</a>, &amp;<a class="code" href="structwhd__netif__funcs.html">whd_netif_funcs</a>) ;</div><div class="line"></div><div class="line">    <span class="comment">// Attach a bus SDIO or SPI</span></div><div class="line">    <a class="code" href="group__busapi.html#ga9f08c5241843cbe2ef06ffa8bfb5118d">whd_bus_sdio_attach</a>(whd_driver, &amp;whd_sdio_cfg, &amp;sdhc_obj);</div><div class="line">    <span class="comment">//or whd_bus_spi_attach(whd_driver, &amp;whd_spi_cfg, &amp;spi_obj);</span></div><div class="line"></div><div class="line">    ...</div><div class="line"></div><div class="line">    <span class="comment">// Switch on Wifi, download firmware and create a primary interface, returns whd_interface_t</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga1c8bf41b593cb947266f8690d495f381">whd_wifi_on</a>(whd_driver, &amp;prim_ifp );</div><div class="line"></div><div class="line">    <span class="comment">// Add the secondary interface. Secondary interface can only be used as AP</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga553c009e9f6f856dfe243d745e21bbf9">whd_add_secondary_interface</a>(whd_driver, mac_addr, &amp;sec_ifp );</div><div class="line"></div><div class="line">    <span class="comment">// Join to AP - Note that it doesn&#39;t take whd_driver, instead whd_interface_t</span></div><div class="line">    <a class="code" href="group__wifijoin.html#gac767814ae445f735b51686db20c780be">whd_wifi_join</a>(prim_ifp , <span class="stringliteral">&quot;AP SSID&quot;</span>, <a class="code" href="whd__types_8h.html#aaeeea5666743710aa4f01ff264b27059a2b5521d2587803363849e1987775e78b">WHD_SECURITY_OPEN</a>, security_key, strlen(security_key), NULL);</div><div class="line">    <span class="comment">// whd_ifp will be in STA role from now on</span></div><div class="line"></div><div class="line">    <span class="comment">// Now start AP in secondary interface, then it will be in AP role</span></div><div class="line">    <a class="code" href="group__wifisoftap.html#ga647aebc1d86708017fd11029e2e1a51c">whd_wifi_init_ap</a>(sec_ifp ..)</div><div class="line">    <a class="code" href="group__wifisoftap.html#ga3c9aa99add3f6a6d13e9092bd6e1246b">whd_wifi_start_ap</a>(sec_ifp);</div><div class="line"></div><div class="line">    <span class="comment">// Leave the AP</span></div><div class="line">    <a class="code" href="group__wifijoin.html#ga971ed7d8e459c715aa9bf3c52b563d8b">whd_wifi_leave</a>(prim_ifp );</div><div class="line"></div><div class="line">    <span class="comment">// Stop the AP</span></div><div class="line">    <a class="code" href="group__wifisoftap.html#ga2c6c28512678dc57dabb641c41e30d41">whd_wifi_stop_ap</a>(sec_ifp , ...);</div><div class="line"></div><div class="line">    <span class="comment">// Switch off Wifi</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga422587a9b104a871233a42aceb2141d2">whd_wifi_off</a>(prim_ifp );</div><div class="line"></div><div class="line">    <span class="comment">// Deletes all the interface and De-init the whd, free whd_driver memory</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#gab7d6e59874922e5646e08e52082e32f5">whd_deinit</a>(prim_ifp);</div><div class="line"></div><div class="line">    <span class="comment">// Detach a bus SDIO or SPI</span></div><div class="line">    <a class="code" href="group__busapi.html#gadeed66e792eed64cbb6a0deef1dbe2da">whd_bus_sdio_detach</a>(whd_driver);</div><div class="line">    <span class="comment">//or whd_bus_spi_detach(whd_driver);</span></div><div class="line">}</div></div><!-- fragment --><p> <br />
</p><h2><a class="anchor" id="_WHD_WPA3/WPA2_transition_mode"></a>WHD WPA3/WPA2 transition mode</h2>
<p>The WHD supports WPA3/WPA2 transition mode. In this mode, if the WPA3 AP goes down and a WPA2 AP is started with the same SSID, the STA automatically transitions to join the WPA2 AP. This mode requires two security keys for the join to be completed. <br />
The security keys can be the same or different,one key is for setting the psk passphrase, and second key is for setting WPA3 password but it is highly recommended to use different passwords. <br />
<br />
The following example code shows the flow for execution in WPA3/WPA2 transition mode: </p><div class="fragment"><div class="line">app_start_whd()</div><div class="line">{</div><div class="line">    <a class="code" href="whd_8h.html#ac45015d82e65db891b463066873eca4f">whd_driver_t</a> whd_driver;</div><div class="line">    <a class="code" href="whd_8h.html#a2e544c482ddbb690bbb95ce7174e79a0">whd_interface_t</a> ifp;</div><div class="line"></div><div class="line">    <span class="comment">// Each wifi chip, will have it&#39;s own instance of whd_driver</span></div><div class="line">    <span class="comment">// Each whd_driver may use multiple instance of whd_interface_t structs to define behavior and functionality.</span></div><div class="line">    <span class="comment">// Most of the WHD function calls take this structure as input.</span></div><div class="line">    <span class="comment">// The default primary interface is created automatically at the time of power up of wifi chip, whd_wifi_on(..).</span></div><div class="line">    <span class="comment">// Primary interface is STA/AP role neutral.</span></div><div class="line"></div><div class="line">    <span class="comment">// Call whd_init per wifi chip (in other words per bus slot, two SDIO Wifi chip requires two calls.)</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga286dde2ee65ac3ea5ae67a6e6ef25f0a">whd_init</a>(&amp;whd_driver, &amp;whd_init_cfg, &amp;<a class="code" href="structwhd__resource__source.html">whd_resource_source</a>, &amp;<a class="code" href="structwhd__buffer__funcs.html">whd_buffer_funcs</a>, &amp;<a class="code" href="structwhd__netif__funcs.html">whd_netif_funcs</a>);</div><div class="line"></div><div class="line">    <span class="comment">// Attach a bus SDIO or SPI</span></div><div class="line">    <a class="code" href="group__busapi.html#ga9f08c5241843cbe2ef06ffa8bfb5118d">whd_bus_sdio_attach</a>(whd_driver, &amp;whd_sdio_cfg, &amp;sdhc_obj);</div><div class="line">    <span class="comment">//or whd_bus_spi_attach(whd_driver, &amp;whd_spi_cfg, &amp;spi_obj);</span></div><div class="line">    ...</div><div class="line">    <span class="comment">// Switch on Wifi, download firmware and create a primary interface, returns whd_interface_t</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga1c8bf41b593cb947266f8690d495f381">whd_wifi_on</a>(whd_driver, &amp;ifp);</div><div class="line"></div><div class="line">    <span class="comment">//Enable WHD internal supplicant and set WPA2 passphrase in case of WPA3/WPA2 transition mode</span></div><div class="line">    <span class="comment">//Here, security_key_psk is WPA2 passphrase for WHD_SECURITY_WPA3_WPA2_PSK authentication type</span></div><div class="line">    <a class="code" href="group__wifiutilities.html#gae118219bea1b82ae76a5c1ee5f7f302c">whd_wifi_enable_sup_set_passphrase</a>( ifp, security_key_psk, strlen(security_key_psk), <a class="code" href="whd__types_8h.html#aaeeea5666743710aa4f01ff264b27059af4d58bc2335113f0c70abdbd3019bb61">WHD_SECURITY_WPA3_WPA2_PSK</a> );</div><div class="line"></div><div class="line">    <span class="comment">//11a. Join to AP</span></div><div class="line">    <span class="comment">//Here, security key is WPA3 password</span></div><div class="line">    <a class="code" href="group__wifijoin.html#gac767814ae445f735b51686db20c780be">whd_wifi_join</a>(ifp , <span class="stringliteral">&quot;AP SSID&quot;</span>, <a class="code" href="whd__types_8h.html#aaeeea5666743710aa4f01ff264b27059af4d58bc2335113f0c70abdbd3019bb61">WHD_SECURITY_WPA3_WPA2_PSK</a>, security_key, strlen(security_key), NULL);</div><div class="line"></div><div class="line">    <span class="comment">// Leave the AP</span></div><div class="line">    <a class="code" href="group__wifijoin.html#ga971ed7d8e459c715aa9bf3c52b563d8b">whd_wifi_leave</a>(ifp );</div><div class="line"></div><div class="line">    <span class="comment">// Switch off Wifi</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#ga422587a9b104a871233a42aceb2141d2">whd_wifi_off</a>(ifp );</div><div class="line"></div><div class="line">    <span class="comment">// Deletes all the interface and De-init the whd, free whd_driver memory</span></div><div class="line">    <a class="code" href="group__wifimanagement.html#gab7d6e59874922e5646e08e52082e32f5">whd_deinit</a>(ifp);</div><div class="line"></div><div class="line">    <span class="comment">// Detach a bus SDIO or SPI</span></div><div class="line">    <a class="code" href="group__busapi.html#gadeed66e792eed64cbb6a0deef1dbe2da">whd_bus_sdio_detach</a>(whd_driver);</div><div class="line">    <span class="comment">//or whd_bus_spi_detach(whd_driver);</span></div><div class="line">}</div></div><!-- fragment --><p><br />
 </p>
<h1><a class="anchor" id="whd_design"></a>
Internals of WHD</h1>
<p>The WHD consists of various internal modules as shown in the following diagram and explained in the following sections. Once the WHD is powered up, the WLAN Bus specific init sequence is completed, and the WLAN chip is ready for operation. </p><div class="image"> <img src="whd_design.png" alt="whd_design.png" width="600px" class="inline"/>
</div><p> <br />
 </p><h2><b>FW Download Module</b></h2>
<p>This module downloads the WLAN Firmware, NVRAM, and CLM file using HAL Resource API. This module does not use the services of control or data path module. It directly accesses the "WHD Bus Interface" to write the resources. After download is completed, this module allows the WLAN firmware to run.<br />
<br />
 </p><h2><b>WLAN Chip Logging Module</b></h2>
<p>This module is responsible for obtaining the WLAN Chip logs using the WHD Debug APIs.<br />
<br />
 </p><h2><b>Control Module</b></h2>
<p>IOCTLs provide control access to the WLAN Chip, and this module routes all these control messages to/from the WLAN chip.<br />
<br />
 </p><h2><b>Data Module</b></h2>
<p>This module handles User Data received in the TCP/IP interface. It also to sends the User Data received from the WLAN Chip.<br />
<br />
 </p><h2><b>Event Module</b></h2>
<p>Event module handles the events generated from the WLAN chip. It also exposes a function for the application to register for limited set of events and process them.<br />
<br />
 </p><h2><b>Protocol Module</b></h2>
<p>Any packet sent to the WLAN chip needs to have a Protocol Header. Protocol Headers are of two types: </p><ul>
<li>
CDC (for control packet like IOCTL and IOVAR) </li>
<li>
BDC (for User Data or ethernet packets from TCP/IP layer)</li>
</ul>
<p>The protocol layer is bus independent and is required for either SDIO/SPI/USB.</p>
<ul>
<li>
<b>CDC Layer</b> The Control Module sends messages to this CDC layer, which adds a 16-byte header known as CDC header. The following shows the header details: <div class="image"> <img src="cdc_msg.png" alt="cdc_msg.png" width="220px" align="left" class="inline"/>
 </div><br />
<br />
<br />
 <div class="fragment"><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span></div><div class="line">{</div><div class="line">    uint32_t cmd;     <span class="comment">// ioctl command value</span></div><div class="line">    uint32_t len;     <span class="comment">// lower 16: output buflen; upper 16: input buflen (excludes header)</span></div><div class="line">    uint32_t flags;   <span class="comment">// flag defns given in bcmcdc.h</span></div><div class="line">    uint32_t status;  <span class="comment">// status code returned from the device</span></div><div class="line">}cdc_header_t;</div></div><!-- fragment --> <br />
</li>
<li>
<b>BDC Layer</b> The User Data Module sends messages to the BDC Layer. It adds a 4-byte header known as the BDC header. The following shows the header details: <div class="image" align="left"> <img src="bdc_msg.png" alt="bdc_msg.png" width="220px" align="left" class="inline"/>
 </div><br />
<br />
<br />
 <div class="fragment"><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span></div><div class="line">{</div><div class="line">   uint8_t flags;        <span class="comment">// Flags</span></div><div class="line">   uint8_t priority;     <span class="comment">// 802.1d Priority (low 3 bits)</span></div><div class="line">   uint8_t flags2;</div><div class="line">   uint8_t data_offset;  <span class="comment">// Offset from end of BDC header to packet data, in 4-uint8_t words.</span></div><div class="line">                         <span class="comment">// Leaves room for optional headers.</span></div><div class="line">} bdc_header_t;</div></div><!-- fragment --> </li>
</ul>
<p><br />
</p><h2><b>Bus Layer</b></h2>
<p>The Bus layer provides bus level protocol handling. For SDIO, a bus protocol known as SDPCM is used.<br />
 </p><ul>
<li>
<b>SDPCM - SDIO/SPI Bus Layer</b> SDPCM Layer takes care of:<br />
 <ul>
<li>
Adding a Sequence number to packet sent to WLAN Chip </li>
<li>
Flow control between WHD and WLAN Chip</li>
</ul>
SDPCM layer adds a fixed 10-byte header and packet format as below: <br />
<div class="image"> <img src="sdpcm_msg.png" alt="sdpcm_msg.png" width="220px" align="left" class="inline"/>
 </div> <br />
<br />
<br />
<br />
</li>
<li>
<b>SDPCM Header</b> <div class="fragment"><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span></div><div class="line">{</div><div class="line">  uint16_t  frametag[2];      <span class="comment">// SDPCM packet size</span></div><div class="line">  uint8_t sequence;           <span class="comment">// Sequence number of pkt</span></div><div class="line">  uint8_t channel_and_flags;  <span class="comment">// IOCTL/IOVAR or User Data or Event</span></div><div class="line">  uint8_t next_length;</div><div class="line">  uint8_t header_length;      <span class="comment">// Offset to BDC or CDC header</span></div><div class="line">  uint8_t wireless_flow_control;</div><div class="line">  uint8_t bus_data_credit;    <span class="comment">// Credit from WLAN Chip</span></div><div class="line">  uint8_t _reserved[2];</div><div class="line">} sdpcm_header_t;</div></div><!-- fragment --> <br />
</li>
<li>
<b>SDIO - SDPCM Flow control</b> Before sending any data to the WLAN, the SDPCM Layer must wait for credit from WLAN chip. Credit is sent by the WLAN either in a SDPCM header packet or as piggy-banked information in a RX User Data packet. The SDPCM Layer should not send any packet if no credit is available. <br />
<br />
<div class="image"> <img src="sdpcm_flow.png" alt="sdpcm_flow.png" width="450px" align="left" class="inline"/>
 </div><br />
</li>
</ul>
<p><br />
</p><h2>Packet Engine</h2>
<p>All the control or User Data is queued in a link list in this layer. Once the credit is available, this layer sends the data to WLAN chip. Also, this layer checks for any RX data from WLAN Chip and sends the data to host TCP/IP stack via its TCP/IP interface. </p><div class="image"> <br />
<img src="data_flow.png" alt="data_flow.png" width="450px" align="left" class="inline"/>
 </div><p><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
 <br />
<br />
</p><h2>WHD Bus Interface</h2>
<p>This module provides bus independent access functions to the packet engine/sdpcm layer. It is primarily used to keep the access functions common between SDIO/SPI. <br />
<br />
</p><h2>SDIO HAL Interface</h2>
<p>Use the CY HAL interface to access the SDIO Host Controller Hardware. It is external to the WHD driver. <br />
<br />
</p><h3><b>SPI HAL Interface</b></h3>
<p>Use the CY HAL interface to access the SPI Host Controller Hardware. It is external to the WHD driver <br />
 <br />
 <br />
 </p>
<h1><a class="anchor" id="apis"></a>
WHD API</h1>
<p>The WHD provides services in the form of the WLAN API which can be used by layers above the WHD. Broadly, the WLAN API can be classified into the following: </p><ul>
<li>
Basic API (like scan, join) </li>
<li>
Intermediate API (like SoftAP) </li>
<li>
Advanced API (to send direct IOCTL to WLAN Chip)</li>
</ul>
<p>Based on the functionality, APIs can be classified as follows: </p><ul>
<li>
<a href="group__busapi.html">WHD Bus API</a> </li>
<li>
<a href="group__buffif.html">WHD Buffer Interface API</a> </li>
<li>
<a href="group__netif.html">WHD Network Interface API</a> </li>
<li>
<a href="group__res.html">WHD Resource API</a> </li>
<li>
<a href="group__event.html">WHD Wi-Fi Event handling API</a> </li>
<li>
<a href="group__wifi.html">WHD Wi-Fi API</a> <ul>
<li>
<a href="group__wifimanagement.html">WHD Wi-Fi Management API</a> </li>
<li>
<a href="group__wifijoin.html">WHD Wi-Fi Join, Scan and Halt API</a> </li>
<li>
<a href="group__wifiutilities.html">WHD Wi-Fi Utility API</a> </li>
<li>
<a href="group__wifisoftap.html">WHD Wi-Fi SoftAP API</a> </li>
<li>
<a href="group__wifipowersave.html">WHD Wi-Fi Power Save API</a> </li>
<li>
<a href="group__wifiioctl.html">WHD Wi-Fi IOCTL Set/Get API</a> </li>
<li>
<a href="group__dbg.html">WHD Wi-Fi Debug API</a> </li>
</ul>
</li>
</ul>
<p><br />
 </p>
</div></div><!-- PageDoc -->
</div><!-- contents -->
</div><!-- doc-content -->
    <!-- start footer part -->
    <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
      <ul>
        <li class="footer">Copyright Cypress Corporation.</li>
      </ul>
    </div>
  </body>
</html>
